package csc.fresher.view;

import java.io.Serializable;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import csc.fresher.commons.BankingConstant;
import csc.fresher.dao.CustomerDao;
import csc.fresher.dao.DepositAccountDao;
import csc.fresher.dao.DepositAccountTransactionDao;
import csc.fresher.dao.InternetAccountDAO;
import csc.fresher.entity.AccountState;
import csc.fresher.entity.Customer;
import csc.fresher.entity.DepositAccount;
import csc.fresher.entity.InternetAccount;
import csc.fresher.entity.DepositTransaction;
import csc.fresher.entity.TransactionState;
import csc.fresher.entity.TransactionType;
import csc.fresher.entity.DepositTransferInfo;
import csc.fresher.service.DepositAccountTransactionService;

@ManagedBean
@SessionScoped
public class TransferMoneyManageBean implements Serializable {
	/**
	 * 
	 */
	private Double fund;
	private static final long serialVersionUID = 1L;
	private Long accountNumber;
	@ManagedProperty(value = "#{internetLoginManageBean}")
	private InternetLoginManageBean cmb;
	@ManagedProperty(value = "#{depositAccountTransactionServiceImpl}")
	DepositAccountTransactionService depositAccountTransactionServiceImpl;
	@ManagedProperty(value = "#{internetAccountDAOImpl}")
	private InternetAccountDAO internetAcountDAO;
	@ManagedProperty(value = "#{customerDaoImpl}")
	private CustomerDao customerDao;
	private Long accounNumChoosen;
	@ManagedProperty(value = "#{customerManageBean}")
	CustomerManageBean customerManageBean;
	@ManagedProperty(value = "#{depositAccountTransactionDaoImpl}")
	private DepositAccountTransactionDao depositAccountTransactionDaoImpl;
	private String content;
	private DepositAccount transferAcc;
	private int showtxsize;

	public int getShowtxsize() {
		return showtxsize;
	}

	public void setShowtxsize(int showtxsize) {
		this.showtxsize = showtxsize;
	}

	public DepositAccountTransactionService getDepositAccountTransactionServiceImpl() {
		return depositAccountTransactionServiceImpl;
	}

	public void setDepositAccountTransactionServiceImpl(
			DepositAccountTransactionService depositAccountTransactionServiceImpl) {
		this.depositAccountTransactionServiceImpl = depositAccountTransactionServiceImpl;
	}

	private DepositAccount receiveAcc;
	private List<DepositTransferInfo> showtx = new ArrayList<DepositTransferInfo>();

	public double getReceiverBalanceAfter() {
		return receiverBalanceAfter;
	}

	public void setReceiverBalanceAfter(double receiverBalanceAfter) {
		this.receiverBalanceAfter = receiverBalanceAfter;
	}

	public double getSenderBalanceAfter() {
		return senderBalanceAfter;
	}

	public void setSenderBalanceAfter(double senderBalanceAfter) {
		this.senderBalanceAfter = senderBalanceAfter;
	}

	public DepositTransaction getTransactionFrom() {
		return transactionFrom;
	}

	public void setTransactionFrom(DepositTransaction transactionFrom) {
		this.transactionFrom = transactionFrom;
	}

	public DepositTransaction getTransactionTo() {
		return transactionTo;
	}

	public void setTransactionTo(DepositTransaction transactionTo) {
		this.transactionTo = transactionTo;
	}

	private double receiverBalanceAfter;
	private double senderBalanceAfter;
	private DepositTransaction transactionFrom;
	private DepositTransaction transactionTo;
	private Customer receiveCustomer;

	public DepositAccountTransactionDao getDepositAccountTransactionDaoImpl() {
		return depositAccountTransactionDaoImpl;
	}

	public void setDepositAccountTransactionDaoImpl(
			DepositAccountTransactionDao depositAccountTransactionDaoImpl) {
		this.depositAccountTransactionDaoImpl = depositAccountTransactionDaoImpl;
	}

	@ManagedProperty(value = "#{depositAccountDaoImpl}")
	DepositAccountDao depositDao;

	public String confirmTransfer() {
		InternetAccount internetAcc = cmb.getAcc();

		FacesContext c = FacesContext.getCurrentInstance();
		if (internetAcc != null) {
			if (accounNumChoosen != accountNumber) {
				transferAcc = depositDao
						.getDepositAccountByDepositAccountID(accounNumChoosen);
				receiveAcc = depositDao
						.getDepositAccountByDepositAccountID(accountNumber);
				if (transferAcc.getAccountState() != AccountState.ACTIVE) {
					c.addMessage(
							null,
							new FacesMessage(
									"Account is not active, please choose another account"));

				} else if (receiveAcc == null) {
					c.addMessage(null, new FacesMessage(
							"Account not exist, please try again!"));
				} else if (receiveAcc.getAccountState() != AccountState.ACTIVE) {
					c.addMessage(
							null,
							new FacesMessage(
									"Account of receiver is not active, please choose another account"));
				} else if (transferAcc.getAccountBalance() < fund) {
					c.addMessage(null, new FacesMessage(
							"Balance is not enough, please try again!"));
				} else {
					receiveCustomer = customerDao.getCustomerByID(receiveAcc
							.getCustomerID());
					transferCus = customerDao.getCustomerByID(transferAcc
							.getCustomerID());
					return "confirmtransfer";
				}
			} else {
				c.addMessage(null, new FacesMessage(
						"Cannot transfer to same account!"));
			}
			return "transfer";
		}
		return "login";
	}

	public String transfer() {
		Date date = new Date();
		double senderAB = transferAcc.getAccountBalance() - this.fund;
		double receiverAB = receiveAcc.getAccountBalance() + this.fund;
		this.senderBalanceAfter = senderAB;
		this.receiverBalanceAfter = receiverAB;

		this.transactionFrom = new DepositTransaction(fund, new Timestamp(
				date.getTime()), new Timestamp(date.getTime()),
				transferAcc.getAccountBalance(), senderBalanceAfter,
				TransactionType.TRANSFER, receiveAcc.getAccountNumber(),
				transferAcc.getAccountNumber(), TransactionState.HOLD,
				transferAcc.getAccountNumber(),
				BankingConstant.DEFAULT_SYSTEM_USER_ID,
				BankingConstant.DEFAULT_SYSTEM_USER_ID, true, content);
		long returnID = depositAccountTransactionServiceImpl
				.transferFunds(transactionFrom);
		fund = null;
		accounNumChoosen = null;
		accountNumber = null;
		if (returnID > 0) {
			return "transfercomplete";
		}
		return "transfercomplete";

	}

	public CustomerManageBean getCustomerManageBean() {
		return customerManageBean;
	}

	public void setCustomerManageBean(CustomerManageBean customerManageBean) {
		this.customerManageBean = customerManageBean;
	}

	public String cancel() {
		fund = null;
		accounNumChoosen = null;
		accountNumber = null;
		content="";
		return "welcomepage";
	}

	public String transferStatus() {
		showtx.clear();
		List<DepositTransaction> tx = new ArrayList<DepositTransaction>();
		tx = depositAccountTransactionDaoImpl
				.searchTransactionByCustomerCardID(customerDao.getCustomerByID(
						cmb.getAcc().getCustomerID()).getIdCardNumber());
		for (int i = 0; i < tx.size(); i++) {
			if (TransactionState.HOLD.equals(tx.get(i).getTransactionState())) {
				Customer receivecus = customerDao.getCustomerByID(depositDao
						.getCustomerAccountByID(tx.get(i).getReceiverID())
						.getCustomerID());
				DepositTransferInfo txi = new DepositTransferInfo(tx.get(i),
						receivecus);
				showtx.add(txi);
			}

		}
		showtxsize = showtx.size();
		return "transferstatus";
	}

	public Customer getReceiveCustomer() {
		return receiveCustomer;
	}

	public void setReceiveCustomer(Customer receiveCustomer) {
		this.receiveCustomer = receiveCustomer;
	}

	public DepositAccountDao getDepositDao() {
		return depositDao;
	}

	public void setDepositDao(DepositAccountDao depositDao) {
		this.depositDao = depositDao;
	}

	public DepositAccount getTransferAcc() {
		return transferAcc;
	}

	public void setTransferAcc(DepositAccount transferAcc) {
		this.transferAcc = transferAcc;
	}

	public DepositAccount getReceiveAcc() {
		return receiveAcc;
	}

	public void setReceiveAcc(DepositAccount receiveAcc) {
		this.receiveAcc = receiveAcc;
	}

	public List<DepositTransferInfo> getShowtx() {
		return showtx;
	}

	public void setShowtx(List<DepositTransferInfo> showtx) {
		this.showtx = showtx;
	}

	public Long getAccountNumber() {
		return accountNumber;
	}

	public void setAccountNumber(Long accountNumber) {
		this.accountNumber = accountNumber;
	}

	public Long getAccounNumChoosen() {
		return accounNumChoosen;
	}

	public void setAccounNumChoosen(Long accounNumChoosen) {
		this.accounNumChoosen = accounNumChoosen;
	}

	public InternetLoginManageBean getCmb() {
		return cmb;
	}

	public InternetAccountDAO getInternetAcountDAO() {
		return internetAcountDAO;
	}

	public void setInternetAcountDAO(InternetAccountDAO internetAcountDAO) {
		this.internetAcountDAO = internetAcountDAO;
	}

	public CustomerDao getCustomerDao() {
		return customerDao;
	}

	public void setCustomerDao(CustomerDao customerDao) {
		this.customerDao = customerDao;
	}

	public void setCmb(InternetLoginManageBean cmb) {
		this.cmb = cmb;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	public Double getFund() {
		return fund;
	}

	public void setFund(Double fund) {
		this.fund = fund;
	}

	private Customer transferCus;

	public Customer getTransferCus() {
		return transferCus;
	}

	public void setTransferCus(Customer transferCus) {
		this.transferCus = transferCus;
	}

}